"""
专门测试在soap:Body元素上添加命名空间声明的功能
目标：在<soap:Body>标签上添加xmlns:test声明，而不是作为子节点添加
"""

from com.tools.Xml_Utils.xml_utils import XmlUtils


def test_add_namespace_declaration_to_body_element():
    """
    测试在soap:Body元素上添加命名空间声明
    """
    print("测试在soap:Body元素上添加命名空间声明:")
    
    # 原始SOAP XML报文
    soap_xml = '''<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
               xmlns:web="http://www.webserviceX.NET">
    <soap:Header/>
    <soap:Body>
        <web:GetWeather>
            <web:CityName>Beijing</web:CityName>
            <web:CountryName>China</web:CountryName>
        </web:GetWeather>
    </soap:Body>
</soap:Envelope>'''
    
    print("原始SOAP XML:")
    print(soap_xml)
    
    # 加载XML
    xml_obj = XmlUtils(xml_string=soap_xml)
    
    # 验证初始状态
    print("\n验证初始命名空间:")
    namespaces = xml_obj.get_namespaces()
    print(f"初始命名空间: {namespaces}")
    
    # 使用XmlUtils工具类的set_element_namespace_declaration方法为Body元素添加命名空间声明
    print("\n使用XmlUtils工具类的set_element_namespace_declaration方法为Body元素添加xmlns:test='https://test.com'命名空间声明:")
    result = xml_obj.set_element_namespace_declaration("//soap:Body", "test", "https://test.com")
    print(f"设置命名空间声明结果: {result}")
    
    # 验证命名空间声明是否添加成功
    namespaces = xml_obj.get_namespaces()
    print(f"更新后的命名空间: {namespaces}")
    
    # 检查test命名空间是否已添加
    has_test_namespace = "test" in namespaces and namespaces["test"] == "https://test.com"
    print(f"test命名空间已添加: {has_test_namespace}")
    assert has_test_namespace == True
    
    # 添加test命名空间元素进行验证
    test_element = xml_obj.add_element_with_namespace(
        "//soap:Body",
        "TestData",
        "test",
        "https://test.com",
        "测试数据",
        {"source": "direct"}
    )
    
    if test_element is not None:
        print("成功添加test命名空间元素")
    else:
        print("添加test命名空间元素失败")
    
    # 转换为字符串并验证
    xml_string = xml_obj.to_string(pretty_print=True)
    print("\n最终XML字符串:")
    print(xml_string)
    
    # 验证关键内容 - 确保命名空间声明在Body元素上
    assert "xmlns:test=\"https://test.com\"" in xml_string
    assert "<soap:Body xmlns:test=" in xml_string  # 确保声明在Body元素上
    assert "测试数据" in xml_string
    assert "source=\"direct\"" in xml_string
    
    # 特别验证Body元素上有命名空间声明
    lines = xml_string.split('\n')
    body_line = None
    for line in lines:
        if "<soap:Body" in line:
            body_line = line.strip()
            break
    
    if body_line:
        print(f"\nBody元素行: {body_line}")
        assert "xmlns:test=\"https://test.com\"" in body_line
        print("验证成功：命名空间声明已正确添加到Body元素上")
    else:
        print("未找到Body元素行")
        assert False, "未找到Body元素"
    
    print("\n在Body元素上添加命名空间声明测试通过!")


def test_multiple_namespace_declarations():
    """
    测试为Body元素添加多个命名空间声明
    """
    print("\n\n测试为Body元素添加多个命名空间声明:")
    
    # 创建一个简单的SOAP XML
    soap_xml = '''<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header/>
    <soap:Body>
        <data>原始数据</data>
    </soap:Body>
</soap:Envelope>'''
    
    print("原始SOAP XML:")
    print(soap_xml)
    
    # 加载XML
    xml_obj = XmlUtils(xml_string=soap_xml)
    
    # 为Body元素添加多个命名空间声明
    print("\n为Body元素添加多个命名空间声明:")
    
    # 添加第一个命名空间
    result1 = xml_obj.set_element_namespace_declaration("//soap:Body", "test1", "https://test1.com")
    print(f"添加test1命名空间结果: {result1}")
    
    # 添加第二个命名空间
    result2 = xml_obj.set_element_namespace_declaration("//soap:Body", "test2", "https://test2.com")
    print(f"添加test2命名空间结果: {result2}")
    
    # 验证命名空间
    namespaces = xml_obj.get_namespaces()
    print(f"更新后的命名空间: {namespaces}")
    
    assert "test1" in namespaces and namespaces["test1"] == "https://test1.com"
    assert "test2" in namespaces and namespaces["test2"] == "https://test2.com"
    
    # 添加命名空间元素进行验证
    element1 = xml_obj.add_element_with_namespace(
        "//soap:Body",
        "Element1",
        "test1",
        "https://test1.com",
        "数据1"
    )
    
    element2 = xml_obj.add_element_with_namespace(
        "//soap:Body",
        "Element2",
        "test2",
        "https://test2.com",
        "数据2"
    )
    
    # 转换为字符串并验证
    xml_string = xml_obj.to_string(pretty_print=True)
    print("\n最终XML字符串:")
    print(xml_string)
    
    # 验证Body元素上有两个命名空间声明
    lines = xml_string.split('\n')
    body_line = None
    for line in lines:
        if "<soap:Body" in line:
            body_line = line.strip()
            break
    
    if body_line:
        print(f"\nBody元素行: {body_line}")
        assert "xmlns:test1=\"https://test1.com\"" in body_line
        assert "xmlns:test2=\"https://test2.com\"" in body_line
        print("验证成功：两个命名空间声明都已正确添加到Body元素上")
    else:
        print("未找到Body元素行")
        assert False, "未找到Body元素"
    
    # 验证元素已正确添加
    assert "数据1" in xml_string
    assert "数据2" in xml_string
    
    print("\n多个命名空间声明测试通过!")


def test_complex_soap_with_namespace_declaration():
    """
    测试在复杂SOAP XML中为Body元素添加命名空间声明
    """
    print("\n\n测试在复杂SOAP XML中为Body元素添加命名空间声明:")
    
    # 复杂的SOAP XML报文
    soap_xml = '''<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
               xmlns:web="http://www.webserviceX.NET">
    <soap:Header>
        <web:AuthHeader>
            <web:Username>user</web:Username>
            <web:Password>pass</web:Password>
        </web:AuthHeader>
    </soap:Header>
    <soap:Body>
        <web:GetWeather>
            <web:CityName>Beijing</web:CityName>
            <web:CountryName>China</web:CountryName>
        </web:GetWeather>
        <web:GetWeatherResponse>
            <web:GetWeatherResult>
                <![CDATA[<CurrentWeather><Location>Beijing</Location><Time>2023-01-01 12:00:00</Time><Temperature>10C</Temperature></CurrentWeather>]]>
            </web:GetWeatherResult>
        </web:GetWeatherResponse>
    </soap:Body>
</soap:Envelope>'''
    
    print("原始复杂SOAP XML:")
    print(soap_xml)
    
    # 加载XML
    xml_obj = XmlUtils(xml_string=soap_xml)
    
    # 为Body元素添加命名空间声明
    print("\n为Body元素添加xmlns:custom='https://custom.namespace.com'命名空间声明:")
    result = xml_obj.set_element_namespace_declaration("//soap:Body", "custom", "https://custom.namespace.com")
    print(f"设置命名空间声明结果: {result}")
    
    # 验证命名空间声明是否添加成功
    namespaces = xml_obj.get_namespaces()
    print(f"更新后的命名空间: {namespaces}")
    
    has_custom_namespace = "custom" in namespaces and namespaces["custom"] == "https://custom.namespace.com"
    print(f"custom命名空间已添加: {has_custom_namespace}")
    assert has_custom_namespace == True
    
    # 添加custom命名空间元素进行验证
    custom_element = xml_obj.add_element_with_namespace(
        "//soap:Body",
        "CustomData",
        "custom",
        "https://custom.namespace.com",
        "自定义数据",
        {"type": "extended"}
    )
    
    if custom_element is not None:
        print("成功添加custom命名空间元素")
    else:
        print("添加custom命名空间元素失败")
    
    # 转换为字符串并验证
    xml_string = xml_obj.to_string(pretty_print=True)
    print("\n最终XML字符串:")
    print(xml_string)
    
    # 验证关键内容
    assert "xmlns:custom=\"https://custom.namespace.com\"" in xml_string
    assert "自定义数据" in xml_string
    assert "type=\"extended\"" in xml_string
    
    # 特别验证Body元素上有命名空间声明
    lines = xml_string.split('\n')
    body_line = None
    for line in lines:
        if "<soap:Body" in line and "xmlns:custom=" in line:
            body_line = line.strip()
            break
    
    if body_line:
        print(f"\nBody元素行: {body_line}")
        assert "xmlns:custom=\"https://custom.namespace.com\"" in body_line
        print("验证成功：命名空间声明已正确添加到Body元素上")
    else:
        # 查找包含Body和命名空间声明的行
        for line in lines:
            if "<soap:Body" in line:
                print(f"Body行: {line.strip()}")
            if "xmlns:custom=" in line:
                print(f"命名空间行: {line.strip()}")
    
    print("\n复杂SOAP XML中添加命名空间声明测试通过!")


if __name__ == "__main__":
    test_add_namespace_declaration_to_body_element()
    test_multiple_namespace_declarations()
    test_complex_soap_with_namespace_declaration()
    print("\n\n所有测试案例完成!")